/* $Header: run_table.c,v 2.2 01/10/02 10:33:17 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME:  run_table.c                                           */
/* ============                                                        */
/*                                                                     */
/* Author:  Rick Wikors, Lesley Freed (additions)                      */
/*                                                                     */
/* MODULE PURPOSE:  To handle entry, deletion and execution of runtime */
/*                  setpoints.                                         */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/


#include <typedefs.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <ramps.h>
#include <zone_config.h>
#include <zone_status.h>
#include <p_status.h>
#include <status.h>
#include <error.h>
#include <i_op.h>
#include <p_ui.h>
#include <zone_ui.h>
#include <string.h>
#include <sig_types.h>
#include <sig_ui.h>
#include <valve_ui.h>
#include <valve.h>
#include <exception.h>
#include <glp.h>
#include <timetable.h>
#include <detector.h>
#include <det_ui.h>
#include <run_ui.h>

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/


/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

static UI_ERR RTTCheckSignalType( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckSignalZero( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckSignalAttn( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckSigRange( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckAuxPress( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckAuxTemp( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckTCDPolarity( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckNPDFuelOnOff( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckFrontOxM( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckBackOxM( RTT_EVENT type, INT32 setpt );
static UI_ERR DummyCheck( RTT_EVENT type, INT32 setpt );

/*****************************/
/*   STATIC VARIABLES        */
/*****************************/

const RTT_INFO Run_Table_Handlers[] = {
{ (TableExecutor) 0,                         0,                  (SETPT) 0,        0 }, /*NULL*/
{ (TableExecutor) RTTSetValve1State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       1 },
{ (TableExecutor) RTTSetValve2State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       2 },
{ (TableExecutor) RTTSetValve3State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       3 },
{ (TableExecutor) RTTSetValve4State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       4 },
{ (TableExecutor) RTTSetValve5State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       5 },
{ (TableExecutor) RTTSetValve6State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       6 },
{ (TableExecutor) RTTSetRelay1State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       7 },
{ (TableExecutor) RTTSetRelay2State,        RTTCheckValveOnOff,  RTT_VALVE_TYPE,       8 },
{ (TableExecutor) RTTSetMultiValve,         RTTCheckMultiValve,  RTT_MULTI_VALVE_TYPE, 0 },
{ (TableExecutor) RTTSetSignal1Type,        RTTCheckSignalType,  RTT_SIGNAL_DEF,       1 },
{ (TableExecutor) RTTSetSignal2Type,        RTTCheckSignalType,  RTT_SIGNAL_DEF,       2 },
{ (TableExecutor) RTTSetSignal1Zero,        RTTCheckSignalZero,  RTT_SIGNAL_ZERO,      1 },
{ (TableExecutor) RTTSetSignal2Zero,        RTTCheckSignalZero,  RTT_SIGNAL_ZERO,      2 },
{ (TableExecutor) RTTSetSignal1Attn,        RTTCheckSignalAttn,  RTT_SIGNAL_ATTN,      1 },
{ (TableExecutor) RTTSetSignal2Attn,        RTTCheckSignalAttn,  RTT_SIGNAL_ATTN,      2 },
{ (TableExecutor) RTTSetSignal1Range,       RTTCheckSigRange,    RTT_SIGNAL_RANGE,     1 },
{ (TableExecutor) RTTSetSignal2Range,       RTTCheckSigRange,    RTT_SIGNAL_RANGE,     2 },
{ (TableExecutor) RTTSetAux3Pres,           RTTCheckAuxPress,    RTT_AUX_TYPE,         3 },
{ (TableExecutor) RTTSetAux4Pres,           RTTCheckAuxPress,    RTT_AUX_TYPE,         4 },
{ (TableExecutor) RTTSetAux5Pres,           RTTCheckAuxPress,    RTT_AUX_TYPE,         5 },
{ (TableExecutor) RTTSetFrntTCDNegPolarity, RTTCheckTCDPolarity, RTT_F_DET_POLARITY,   (U_INT8)FRONT},
{ (TableExecutor) RTTSetBackTCDNegPolarity, RTTCheckTCDPolarity, RTT_B_DET_POLARITY,   (U_INT8)BACK },
{ (TableExecutor) RTTSetFrntDetFuelState,   RTTCheckNPDFuelOnOff,RTT_F_DET_FUEL_ON_OFF,(U_INT8)FRONT},
{ (TableExecutor) RTTSetBackDetFuelState,   RTTCheckNPDFuelOnOff,RTT_F_DET_FUEL_ON_OFF,(U_INT8)BACK },
{ (TableExecutor) RTTSetAux1Temp,           RTTCheckAuxTemp,     RTT_AUX_TEMP,         1},
{ (TableExecutor) RTTSetAux2Temp,           RTTCheckAuxTemp,     RTT_AUX_TEMP,         2},
{ (TableExecutor) RTTSetCPFCtlFrnt1,        RTTCheckFrontOxM,    RTT_F_OIM,  1},
{ (TableExecutor) RTTSetCPFCtlFrnt2,        RTTCheckFrontOxM,    RTT_F_OIM,  2},
{ (TableExecutor) RTTSetCPFCtlFrnt3,        RTTCheckFrontOxM,    RTT_F_OIM,  3},
{ (TableExecutor) RTTSetCPFCtlFrnt4,        RTTCheckFrontOxM,    RTT_F_OIM,  4},
{ (TableExecutor) RTTSetCPFCtlBack1,        RTTCheckBackOxM,     RTT_B_OIM,  1},
{ (TableExecutor) RTTSetCPFCtlBack2,        RTTCheckBackOxM,     RTT_B_OIM,  2},
{ (TableExecutor) RTTSetCPFCtlBack3,        RTTCheckBackOxM,     RTT_B_OIM,  3},
{ (TableExecutor) RTTSetCPFCtlBack4,        RTTCheckBackOxM,     RTT_B_OIM,  4},
{ (TableExecutor) RTTStoreSignal1Value,     DummyCheck, RTT_SIGNAL_VALUE,    1},
{ (TableExecutor) RTTStoreSignal2Value,     DummyCheck, RTT_SIGNAL_VALUE,    2},
{ (TableExecutor) RTTSignal1ZeroLessVal,    DummyCheck, RTT_ZERO_LESS_VALUE, 1},
{ (TableExecutor) RTTSignal2ZeroLessVal,    DummyCheck, RTT_ZERO_LESS_VALUE, 2},
{ (TableExecutor) RTTFreezeSignal1,         DummyCheck, RTT_SIGNAL_VALUE,    1},
{ (TableExecutor) RTTFreezeSignal2,         DummyCheck, RTT_SIGNAL_VALUE,    2},
{ (TableExecutor) RTTResumeSignal1,         DummyCheck, RTT_ZERO_LESS_VALUE, 1},
{ (TableExecutor) RTTResumeSignal2,         DummyCheck, RTT_ZERO_LESS_VALUE, 2},
{ (TableExecutor) RTTSetOEMCtlFrnt5,        RTTCheckFrontOxM,    RTT_F_OIM,  5},
{ (TableExecutor) RTTSetOEMCtlFrnt7,        RTTCheckFrontOxM,    RTT_F_OIM,  7},
{ (TableExecutor) RTTSetOEMCtlBack5,        RTTCheckBackOxM,     RTT_B_OIM,  5},
{ (TableExecutor) RTTSetOEMCtlBack7,        RTTCheckBackOxM,     RTT_B_OIM,  7},
};

RESOURCE Run_Table_Exclusive_Lock;

/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

void DeleteEntryInTable (pTIME_TABLE table,  U_INT8 entry_number )
{

    (void) memmove( (void *)&(table->Table[ entry_number    ]),              /* dest   */
                    (void *)&(table->Table[ entry_number +1 ]),              /* source */
        (NUM_AVAIL_ENTRIES - entry_number -1 )*sizeof(TIME_TABLE_ENTRY) );   /* length */

    table->Table[ NUM_AVAIL_ENTRIES -1 ].Type = (U_INT8) Available_Entry;
    table->Table[ NUM_AVAIL_ENTRIES -1 ].Time = (INT32) 0xffffffff;       /* maximum allowed run time */
    table->Table[ NUM_AVAIL_ENTRIES -1 ].Parm = (INT32) 0xdeadc0ed;


    if ( table->Current_Entry_Index > entry_number ) table->Current_Entry_Index--;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

U_INT8 InsertEntryInTable (pTIME_TABLE table, U_INT32 time, U_INT8 type, INT32 parm )
{

    U_INT8 start;
    U_INT8 end;

    /* find first available, (last byte to move) */

    for ( end = 0 ; table->Table[end].Type != (U_INT8) Available_Entry ; end++ ) {};

    for ( start = 0 ;
         (( table->Table[start].Type != (U_INT8) Available_Entry ) &&
          ( table->Table[start].Time <= (INT32) time ))  ;
         start++ ) {};


    (void) memmove ( (void *)&(table->Table[ start +1 ]),          /* dest   */
                     (void *)&(table->Table[ start    ]),          /* source */
                              (end-start)*sizeof(TIME_TABLE_ENTRY) );      /* length */

    table->Table[ start ].Time = time;
    table->Table[ start ].Type = type;
    table->Table[ start ].Parm = parm;

    if ( start < table->Current_Entry_Index )  table->Current_Entry_Index++;

    return start;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

static INT32 GetRTTSetptNum( U_INT8 type )
{
   switch ( Run_Table_Handlers[type].setpt_name )
   {
      case RTT_F_OIM:
         return (INT32)GetCPFCtlLabel(FRONT,Run_Table_Handlers[type].setpt_num);
      case RTT_B_OIM:
         return (INT32)GetCPFCtlLabel(BACK,Run_Table_Handlers[type].setpt_num);
      default:  return (INT32)Run_Table_Handlers[type].setpt_num;
   }
}

UI_ERR AddTimeTableEntry ( INT32 time, U_INT8 type, INT32 parm, U_INT8 *new_entry_num )

/**end_proto**/
{
    UI_ERR return_value;

    return_value = CheckTimeSetpt( time );
    if ( return_value != OK ) return return_value;

    LockResource( &Run_Table_Exclusive_Lock );

    if ( Active_Wkfile.Run_Time_Table.Table[NUM_AVAIL_ENTRIES-1].Type == (U_INT8) Available_Entry )
    {
          /* NOTE: user interface numbers entries from 1 so we add 1 here:  */
          *new_entry_num = 1 + InsertEntryInTable( &Active_Wkfile.Run_Time_Table,
                                              TimeToMilliSecs( time ), type, parm );

          /* this entry could be the only entry in the table, yet it's */
          /* execution time may have past.  in that case, skip it      */
          if ((time < (INT32) GetRunTime()) &&  RunInProgress() )
          {
              if ( Active_Wkfile.Run_Time_Table.Current_Entry_Index == *new_entry_num - 1 )
              {
                   Active_Wkfile.Run_Time_Table.Current_Entry_Index++;
              }
          }

          LogSetptChange( Run_Table_Handlers[type].setpt_name,
                          GetRTTSetptNum(type),
                          *new_entry_num );

          return_value = OK;
    }
    else
    {
          return_value = TABLE_FULL;
    }

    ReleaseResource( &Run_Table_Exclusive_Lock );

    return return_value;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

UI_ERR DeleteTimeTableEntry ( U_INT8 entry_num )

/**end_proto**/
{

    UI_ERR return_value;

    LockResource( &Run_Table_Exclusive_Lock );

    if (( entry_num > NUM_AVAIL_ENTRIES ) ||
        ( Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Type == (U_INT8) Available_Entry ))
    {
          return_value = INVALID_PARAM;
    }
    else
    {
         DeleteEntryInTable ( &Active_Wkfile.Run_Time_Table, entry_num-1 );
         return_value = OK;

         LogSetptChange( RTT_ENTRY_DELETED, 0, entry_num );
    }

    ReleaseResource( &Run_Table_Exclusive_Lock );

    return return_value;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

UI_ERR GetTimeTableEntry ( U_INT8 entry_num, INT32 *time, U_INT8 *type, INT32 *parm )

/**end_proto**/
{

    if ( entry_num > NUM_AVAIL_ENTRIES)
    {
          return INVALID_PARAM;
    }

    if ( Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Type == (U_INT8) Available_Entry )
    {
          return TABLE_ENTRY_EMPTY;
    }
    else
    {
         *time = MilliSecsToTime( Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Time );
         *type = Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Type;
         *parm = Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Parm;
         return OK;
    }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

static SETPT GetRTTSetpt( U_INT8 type, INT32 parm )
{
   switch( type )
   {
      default:
      case FRNT_DET_POLARITY:
      case BACK_DET_POLARITY:
      case VALVE_1:
      case VALVE_2:
      case VALVE_3:
      case VALVE_4:
      case VALVE_5:
      case VALVE_6:
      case VALVE_7:
      case VALVE_8:  return ( parm == (U_INT8)ON ) ? RTT_SETPT_ON : RTT_SETPT_OFF;

      case SIGNAL_1_DEF:
      case SIGNAL_2_DEF:  switch( parm )
                          {
                             case DETA_SIGNAL:      return RTT_DETA_SIGNAL;
                             case DETB_SIGNAL:      return RTT_DETB_SIGNAL;
                             case DETA_B_SIGNAL:    return RTT_DETA_B_SIGNAL;
                             case DETB_A_SIGNAL:    return RTT_DETB_A_SIGNAL;
                             case F_CCOMP1_SIGNAL:  return RTT_F_CCOMP1_SIGNAL;
                             case B_CCOMP1_SIGNAL:  return RTT_B_CCOMP1_SIGNAL;
                             case F_CCOMP2_SIGNAL:  return RTT_F_CCOMP2_SIGNAL;
                             case B_CCOMP2_SIGNAL:  return RTT_B_CCOMP2_SIGNAL;
                             default:
                             case TEST_PLOT_SIGNAL: return RTT_TEST_PLOT_SIGNAL;
                          }

      case SIGNAL_1_ZERO:
      case SIGNAL_2_ZERO:
                   if ( parm == RTT_ZERO_ON_VALUE ) return RTT_SETPT_ON;
                   if ( parm == RTT_ZERO_OFF_VALUE ) return RTT_SETPT_OFF;
                   return RTT_SETPT_TENTHS;

      case SIGNAL_1_ATTN:
      case SIGNAL_2_ATTN:
      case SIGNAL_1_RANGE:
      case SIGNAL_2_RANGE: return RTT_SETPT_INTEGER;

      case AUX_3_PRESSURE:
      case AUX_4_PRESSURE:
      case AUX_5_PRESSURE: switch( GetPresUnits() )
                           {
                              default:
                              case DISPLAY_PSI:  return RTT_SETPT_PSI;
                              case DISPLAY_KPA:  return RTT_SETPT_KPA;
                              case DISPLAY_BAR:  return RTT_SETPT_BAR;
                           }
      case AUX_1_TEMP:
      case AUX_2_TEMP:
                   if ( parm == RTT_TEMP_OFF_VALUE ) return RTT_SETPT_OFF;
                   return RTT_SETPT_INTEGER;

      case FRONT_OIM1:
      case FRONT_OIM2:
      case FRONT_OIM3:
      case FRONT_OIM4:
      case FRONT_OEM5:
      case FRONT_OEM7:
      case BACK_OIM1:
      case BACK_OIM2:
      case BACK_OIM3:
      case BACK_OIM4:
      case BACK_OEM5:
      case BACK_OEM7:
                   if ( parm == RTT_CPF_CTL_OFF ) return RTT_SETPT_OFF;
                   if ( parm == RTT_CPF_CTL_ON ) return RTT_SETPT_ON;
                   return RTT_SETPT_INTEGER;
   }
}

static INT32 GetRTTGlpParm1( U_INT8 type, INT32 parm )
{
   switch( type )
   {
      case AUX_3_PRESSURE: return RTTGetAux3PresDisplay( parm );
      case AUX_4_PRESSURE: return RTTGetAux4PresDisplay( parm );
      case AUX_5_PRESSURE: return RTTGetAux5PresDisplay( parm );
      case AUX_1_TEMP:
      case AUX_2_TEMP:     return TempSetptToDegrees( parm );
      default:             return parm;
   }
}


static BIT8 RTTEventHasParm( U_INT8 /*RTT_EVENT*/ type )
{
   switch( type )
   {
      case STORE_SIGNAL_1_VALUE:
      case STORE_SIGNAL_2_VALUE:
      case SIGNAL_1_ZERO_LESS_VAL:
      case SIGNAL_2_ZERO_LESS_VAL:  return FALSE;

      default: return TRUE;
   }
}

UI_ERR ChangeRunTableEntryParm ( U_INT8 entry_num, INT32 parm )

/**end_proto**/
{
    UI_ERR return_value;
    U_INT8 type;

    LockResource( &Run_Table_Exclusive_Lock );

    if (( entry_num > NUM_AVAIL_ENTRIES) ||
        ( Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Type == (U_INT8) Available_Entry ))
    {
          return_value = INVALID_PARAM;
    }
    else
    {
         Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Parm = parm;

         /* Log the setpoint change for the entry depending upon the type */
         type = Active_Wkfile.Run_Time_Table.Table[entry_num-1].Type;

         /* Some events don't have a parameter */
         if ( RTTEventHasParm( type ) )
         {
            LogSetptChange( GetRTTSetpt(type, parm),
                            GetRTTGlpParm1( type, parm) , entry_num );
         }
         return_value = OK;
    }

    ReleaseResource( &Run_Table_Exclusive_Lock );
    return return_value;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

UI_ERR ChangeRunTableEntryTime ( U_INT8 entry_num, INT32 time, U_INT8 *new_entry_num )

/**end_proto**/
{
    INT32   parm;
    U_INT16 type;
    UI_ERR  return_value;

    return_value = CheckTimeSetpt( time );
    if ( return_value != OK ) return return_value;

    LockResource( &Run_Table_Exclusive_Lock );

    if (( entry_num > NUM_AVAIL_ENTRIES) ||
        ( Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Type == (U_INT8) Available_Entry ))
    {
          return_value = INVALID_PARAM;
    }
    else
    {
         type = Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Type;
         parm = Active_Wkfile.Run_Time_Table.Table[ entry_num-1 ].Parm;
         DeleteEntryInTable ( &Active_Wkfile.Run_Time_Table, entry_num-1 );
         *new_entry_num = InsertEntryInTable ( &Active_Wkfile.Run_Time_Table, TimeToMilliSecs( time ), type, parm )+1;

         /* if this is now the current entry, and it's time is past, skip it! */

         if ( ((*new_entry_num) - 1) == Active_Wkfile.Run_Time_Table.Current_Entry_Index )
         {
              if ((time < (INT32) GetRunTime()) &&  RunInProgress() )
              {
                   Active_Wkfile.Run_Time_Table.Current_Entry_Index++;
              }
         }
         LogSetptChange( RTT_ENTRY_TIME, time, entry_num );
         return_value = OK;
    }

    ReleaseResource( &Run_Table_Exclusive_Lock );
    return return_value;
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void SetUpDefaultRunTimeTable ( void )

/**end_proto**/
{
     U_INT8 i;
                       /* not avail, use whole table! */
     for ( i = 0 ; i < NUM_TIME_TABLE_ENTRIES ; i++ )
     {
          Active_Wkfile.Run_Time_Table.Table[i].Type = (U_INT8)Available_Entry;
          Active_Wkfile.Run_Time_Table.Table[i].Time = (INT32)0xffffffff;
          Active_Wkfile.Run_Time_Table.Table[i].Parm = (INT32)0xffffffff;
     }

     Active_Wkfile.Run_Time_Table.Current_Entry_Index = 0;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/*   only called when RUN_ACTIVE                                       */
/*                                                                     */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ExecuteRunTimeTable ( void )

/**end_proto**/
{

    U_INT8   index;
    TableExecutor handler;
    INT32    parm;

    if (IsrLockResource( &Run_Table_Exclusive_Lock ) == TRUE )
    {

        index = Active_Wkfile.Run_Time_Table.Current_Entry_Index;

        if ( (U_INT32) Active_Wkfile.Run_Time_Table.Table[ index ].Time <= (U_INT32)Run_Clock )
        {
           handler = Run_Table_Handlers[Active_Wkfile.Run_Time_Table.Table[index].Type].handler;
           parm    =  Active_Wkfile.Run_Time_Table.Table[ index ].Parm;
           (*handler)( parm );

           if ( index <= NUM_AVAIL_ENTRIES ) Active_Wkfile.Run_Time_Table.Current_Entry_Index++;
        }

        ReleaseResource( &Run_Table_Exclusive_Lock );
    }
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void ResetRunTablePointer ( void )

/**end_proto**/
{

         Active_Wkfile.Run_Time_Table.Current_Entry_Index = 0;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void UndoRunTableChanges ( void )

/**end_proto**/
{
    U_INT16 p;

 /* undo run time programable values */

/*  REVISION: Valves will NOT reset at end of run.  Run Table */
/*    valve changes are permanent.                            */
/*  ResetValveState();   */

    EvaluateValveReadiness();    /* Catch GSV's that are still ON */

    ResetAuxPressures();
    ResetAuxTemperatures();
    ResetSigPathState();
    ResetTCDState();
    RTTResetDetectorStates();
    UpdateCPFCtlValues();
    for ( p = 0; p < 2 ; p++ ) { RestoreOEMControls( (POSITION)p) ; } ;
    ResetRunTablePointer();
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

INT32 MaxRunTableEntry (void)
{
    INT32   max;
    INT8    i;

    max = 0;

    for (i = 0;
         (Active_Wkfile.Run_Time_Table.Table[i].Type != (U_INT8) Available_Entry ) &&
           (i < NUM_AVAIL_ENTRIES);
         i++)
    {
       max++;
    }

    return max;
}


/***********************************************************************/
/* FUNCTION:  RTTCheckFcns                                             */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

static UI_ERR DummyCheck( RTT_EVENT type, INT32 setpt )
{
   (void)type;
   (void)setpt;
   return OK;
}

static UI_ERR DummyCheck( RTT_EVENT type, INT32 setpt );
static UI_ERR RTTCheckOnOff( INT32 on_off )
{
   if (( on_off == (INT32) ON ) || ( on_off == (INT32) OFF ))
   {
      return OK;
   }
   else
   {
      return INVALID_PARAM;
   }
}

UI_ERR RTTCheckValveOnOff( RTT_EVENT type, INT32 setpt )
{
   VALVE_TYPE valve_type;

   valve_type = GetValveType( Run_Table_Handlers[(U_INT8)type].setpt_num );

   if (( valve_type == NO_VALVE ) || ( valve_type == MULTIPOSITION ))
   {
      return NOT_INSTALLED;
   }
   else
   {
      return RTTCheckOnOff( setpt );
   }
}

UI_ERR RTTCheckMultiValve( RTT_EVENT type, INT32 setpt )
{
   (void) type;
   if ( HaveMultiposValve() )
   {
      return CheckValveStreamNo( setpt );
   }
   else
   {
      return NOT_INSTALLED;
   }
}

static UI_ERR RTTCheckSignalType( RTT_EVENT type, INT32 setpt )
{
   (void) type;
   return CheckSignalType( (SIG_TYPE) setpt );
}

static UI_ERR RTTCheckSignalZero( RTT_EVENT type, INT32 setpt )
{
   (void) type;

   /* We will use reserved value to indicate on/off control */
   if (( setpt == RTT_ZERO_ON_VALUE ) ||( setpt == RTT_ZERO_OFF_VALUE ))
   {
      return OK;
   }

   return CheckSignalZero( setpt );
}

static UI_ERR RTTCheckSignalAttn( RTT_EVENT type, INT32 setpt )
{
   (void) type;
   return CheckSignalAttn( setpt );
}

static UI_ERR RTTCheckSigRange( RTT_EVENT type, INT32 setpt )
{
   (void) type;
   return CheckSignalRange( setpt );
}

static UI_ERR RTTCheckAuxPress( RTT_EVENT type, INT32 setpt )
{
   U_INT16 pres_ui;

   switch ( type )
   {
      default:
      case AUX_3_PRESSURE:  return DcRTTGetValidAux3Pres( setpt, &pres_ui );
      case AUX_4_PRESSURE:  return DcRTTGetValidAux4Pres( setpt, &pres_ui );
      case AUX_5_PRESSURE:  return DcRTTGetValidAux5Pres( setpt, &pres_ui );
   }
}

static UI_ERR RTTCheckAuxTemp( RTT_EVENT type, INT32 setpt )
{
   pZONE_TABLE pzone;

   pzone = (type == AUX_1_TEMP) ? pAUX_1_TEMP : pAUX_2_TEMP;

   if ( setpt == RTT_TEMP_OFF_VALUE )
   {
      return OK;
   }
   else
   {
      return CheckTempSetpt( pzone, setpt );
   }
}

static UI_ERR RTTCheckTCDPolarity( RTT_EVENT type, INT32 setpt )
{
   DET_TYPE det_type;

   det_type = GetDetectorType( (POSITION)Run_Table_Handlers[(U_INT8)type].setpt_num );

   if ( det_type == TCD ) return RTTCheckOnOff( setpt );

   return NOT_INSTALLED;
}

static UI_ERR RTTCheckNPDFuelOnOff( RTT_EVENT type, INT32 setpt )
{
   DET_TYPE det_type;

   det_type = GetDetectorType( (POSITION)Run_Table_Handlers[(U_INT8)type].setpt_num );

   if ( det_type == NPD ) return RTTCheckOnOff( setpt );

   return NOT_INSTALLED;
}

UI_ERR RTTCheckOxM( RTT_EVENT type, INT32 setpt, POSITION position )
{
   INT16 num;

   num = Run_Table_Handlers[(U_INT8)type].setpt_num;

   switch ( GetDetectorType(position))
   {
      case OEM_AIB:
      case OEM_FID:
              if (GetOEMCtlPresence( position, num ))
              {
                 if ( num == 7 ) return CheckOEMXtlValue ( position,  setpt );
                 if (setpt == -1)  /* -1 equals ON in this case */
                 {
                    return CheckOEMCtlOnOff ( position, num, ON );
                 }
                 else
                 {
                    return CheckOEMCtlOnOff ( position, num, OFF );
                 }
              };
   };

   if (GetCPFCtlPresence( position, num ))
   {
      if (( setpt == RTT_CPF_CTL_ON ) || ( setpt == RTT_CPF_CTL_OFF ))
      {
         return OK;
      }

      return CheckCPFCtlValue( position, num, setpt );
   }
   else
   {
      return NOT_INSTALLED;
   }
}

UI_ERR RTTCheckFrontOxM( RTT_EVENT type, INT32 setpt )
{
   return RTTCheckOxM( type, setpt, FRONT );
}

UI_ERR RTTCheckBackOxM( RTT_EVENT type, INT32 setpt )
{
   return RTTCheckOxM( type, setpt, BACK );
}

UI_ERR CheckRunTableType( INT32 type )
{
   if ( ( type <= 0 ) || ( type > (INT32) MAX_RTT_TYPE ) )
   {
      return INVALID_PARAM;
   }

   return OK;
}

/* NOTE:  The following function assumes that the type is
          a valid RTT_EVENT */
UI_ERR CheckRunTableParam( RTT_EVENT type, INT32 param )
{
   return Run_Table_Handlers[(U_INT8)type].check_fcn( type, param );
}


void DeleteEntireTimeTable( void )
{
   U_INT8 type;
   INT32  time, parm;

   while ( GetTimeTableEntry( 1, &time, &type, &parm ) == OK )
   {
      (void) DeleteTimeTableEntry(1);
   }

   (void)time;
   (void)type;
   (void)parm;
}

/* Convert the data comm units for a setpt to internal units */
INT32 GetIuRunTableParm( RTT_EVENT type, INT32 parm )
{
   U_INT16 pres_iu;

   switch( type )
   {
      case AUX_3_PRESSURE:   (void) DcRTTGetValidAux3Pres( parm, &pres_iu );
                             return (INT32)pres_iu;

      case AUX_4_PRESSURE:   (void) DcRTTGetValidAux4Pres( parm, &pres_iu );
                             return (INT32)pres_iu;

      case AUX_5_PRESSURE:   (void) DcRTTGetValidAux5Pres( parm, &pres_iu );
                             return (INT32)pres_iu;

      case AUX_1_TEMP:
      case AUX_2_TEMP:       if ( parm == RTT_TEMP_OFF_VALUE )
                             {
                                return parm;
                             }
                             else
                             {
                                return DegreesToTemp( parm );
                             }


      default:               return parm;

   }
}

/* Convert the setpt to data comm units from internal units */
INT32 GetDcRunTableParm( RTT_EVENT type, INT32 parm )
{
   switch( type )
   {
      case AUX_3_PRESSURE:   return DcRTTGetAux3PresDisplay( parm );

      case AUX_4_PRESSURE:   return DcRTTGetAux4PresDisplay( parm );

      case AUX_5_PRESSURE:   return DcRTTGetAux5PresDisplay( parm );

      case AUX_1_TEMP:
      case AUX_2_TEMP:       if ( parm == RTT_TEMP_OFF_VALUE )
                             {
                                return parm;
                             }
                             else
                             {
                                return TempSetptToDegrees( parm );
                             }

      default:               return parm;

   }
}

INT16 NumRunTableEntries( void )
{
   INT16  i;
   U_INT8 type;
   INT32  time, parm;

   UI_ERR error;

   i = 0;

   error = GetTimeTableEntry( i+1, &time, &type, &parm );

   while ( ( type != (U_INT8) NULL_EVENT ) && ( error == OK ) )
   {
      i++;
      error = GetTimeTableEntry( i+1, &time, &type, &parm );
   }

   (void)time;
   (void)parm;

   return i;
}
